package com.gomoku.model;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class Board {
    public static final int AI = 2;
    public static final int PLAYER = 1;
    public static final int BOARD_SIZE = 15;
    private int[][] grid; // 0: empty, 1: black (player), 2: white (AI)

    public Board() {
        grid = new int[BOARD_SIZE][BOARD_SIZE];
        // Initialize empty board
        for (int i = 0; i < BOARD_SIZE; i++) {
            for (int j = 0; j < BOARD_SIZE; j++) {
                grid[i][j] = 0;
            }
        }
    }

    public boolean isValidMove(int row, int col) {
        return row >= 0 && row < BOARD_SIZE && 
               col >= 0 && col < BOARD_SIZE && 
               grid[row][col] == 0;
    }

    public void makeMove(int row, int col, boolean isAI) {
        grid[row][col] = (isAI ? AI: PLAYER);
    }
    public void undoMove(int row, int col) { grid[row][col] = 0;}

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder(BOARD_SIZE * BOARD_SIZE); // 提前分配容量
        for (int i = 0; i < BOARD_SIZE; i++) {
            for (int j = 0; j < BOARD_SIZE; j++) {
                sb.append(grid[i][j]);
            }
            // 添加换行符或其他分隔符用于调试（可选）
            // sb.append('\n');
        }
        return sb.toString();
    }

    public boolean checkWinCondition() {
        for (int i = 0; i < BOARD_SIZE; i++) {
            for (int j = 0; j < BOARD_SIZE; j++) {
                if (grid[i][j] != 0 && checkWin(i, j)) {
                    return true;
                }
            }
        }
        return false;
    }

    public boolean checkWinConditionForPlayer(int player) {
        for (int i = 0; i < BOARD_SIZE; i++) {
            for (int j = 0; j < BOARD_SIZE; j++) {
                if (grid[i][j] == player && checkWin(i, j)) {
                    return true;
                }
            }
        }
        return false;
    }



    public boolean checkWin(int row, int col) {
        int player = grid[row][col];
        return checkDirection(row, col, 1, 0, player) || // horizontal
               checkDirection(row, col, 0, 1, player) || // vertical
               checkDirection(row, col, 1, 1, player) || // diagonal
               checkDirection(row, col, 1, -1, player);  // anti-diagonal
    }

    private boolean checkDirection(int row, int col, int dRow, int dCol, int player) {
        int count = 1;
        
        // Check forward direction
        int r = row + dRow;
        int c = col + dCol;
        while (r >= 0 && r < BOARD_SIZE && c >= 0 && c < BOARD_SIZE && grid[r][c] == player) {
            count++;
            r += dRow;
            c += dCol;
        }
        
        // Check backward direction
        r = row - dRow;
        c = col - dCol;
        while (r >= 0 && r < BOARD_SIZE && c >= 0 && c < BOARD_SIZE && grid[r][c] == player) {
            count++;
            r -= dRow;
            c -= dCol;
        }
        
        return count >= 5;
    }

    public boolean isFull() {
        for (int i = 0; i < BOARD_SIZE; i++) {
            for (int j = 0; j < BOARD_SIZE; j++) {
                if (grid[i][j] == 0) {
                    return false;
                }
            }
        }
        return true;
    }

    public int[][] getGrid() {
        return grid;
    }

    public void setGrid(int[][] grid) {
        this.grid = grid;
    }

    // Helper method for AI evaluation
    @JsonIgnore
    public int getPiece(int row, int col) {
        return grid[row][col];
    }

    // Deep copy for AI algorithm
    public Board copy() {
        Board newBoard = new Board();
        for (int i = 0; i < BOARD_SIZE; i++) {
            for (int j = 0; j < BOARD_SIZE; j++) {
                newBoard.grid[i][j] = this.grid[i][j];
            }
        }
        return newBoard;
    }

    public void printBoard() {
        for (int i = 0; i < BOARD_SIZE; i++) {
            for (int j = 0; j < BOARD_SIZE; j++) {
                System.out.print(grid[i][j] + " ");
            }
            System.out.println();
        }
    }
} 